package com.xiaofeng.pochi.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.xiaofeng.pochi.common.Page;
import com.xiaofeng.pochi.common.Result;
import com.xiaofeng.pochi.config.Config;
import com.xiaofeng.pochi.pojo.ShopBrand;
import com.xiaofeng.pochi.pojo.ShopOrder;
import com.xiaofeng.pochi.pojo.dto.ShopBrandDto;
import com.xiaofeng.pochi.pojo.vo.ShopBrandVo;
import com.xiaofeng.pochi.service.ShopBrandService;
import com.xiaofeng.pochi.service.ShopOrderService;
import com.xiaofeng.pochi.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA
 *
 * @Author: chc
 * @Date: 2022/08/10/20:12
 * @Description:
 */
@RestController
@RequestMapping("/brand")
@Slf4j
public class ShopBrandController {

    @Autowired
    private ShopBrandService shopBrandService;

    @Autowired
    private WxPayConfig wxPayConfig;

    @Autowired
    private ShopOrderService shopOrderService;


    /**
     * 添加
     *
     * @param shopBrandDto
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public Result<?> save(@RequestBody ShopBrandDto shopBrandDto) {
        shopBrandService.save(shopBrandDto);
        return new Result<>("添加成功");
    }


    /**
     * 修改
     *
     * @param shopBrandDto
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.PUT)
    public Result<?> update(@RequestBody ShopBrandDto shopBrandDto) {
        shopBrandService.update(shopBrandDto);
        return new Result<>("添加成功");
    }

    /**
     * 根据id删除
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
    public Result<?> delete(@PathVariable Long id) {
        shopBrandService.delete(id);
        return new Result<>("删除成功");
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
    public Result<ShopBrandVo> get(@PathVariable Long id) {
        ShopBrandVo vo = shopBrandService.get(id);
        return new Result<>(vo);
    }

    /**
     * 根据id查询用于修改的数据回显
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/getUpdate/{id}", method = RequestMethod.GET)
    public Result<ShopBrandDto> getUpdate(@PathVariable Long id) {
        ShopBrandDto vo  = shopBrandService.getUpdate(id);
        return new Result<>(vo );
    }

    /**
     * 分页查询
     *
     * @param page
     * @return
     */
    @RequestMapping(value = "/getByPage",  method = RequestMethod.POST)
    public Result<Page<ShopBrand>> getByPage(@RequestBody Page<ShopBrand> page) {
        page = shopBrandService.getByPage(page);
        return new Result<>(page);
    }

    /**
     * 根据分类id
     * */
    @RequestMapping(value ="/getByCategoryId/{categoryId}",method = RequestMethod.GET)
    public Result<List<ShopBrand>> getByCategoryId(@PathVariable Long categoryId){
       List<ShopBrand> brandList = shopBrandService.getByCategoryId(categoryId);
        return new Result<>(brandList);
    }


    /**
     * 创建支付订单
     * @param shopOrder
     * @throws Exception
     * @return
     */
    @PostMapping("/pay")
    @ResponseBody
    public ResultInfo<Object> pay(@RequestBody ShopOrder shopOrder) throws Exception {
        String title = "";
        double priceDiscount = 0.01;
        String dateTime = new DateTime().toString("yyyyMMddHHmmssSSS");
        shopOrderService.createPayOrder(shopOrder,dateTime);
        try {
            JSONObject order = new JSONObject();
            order.put("appid", Config.getWeixinMiniAppid());
            order.put("mchid", Config.getWeixinMiniMchId());
            order.put("description", "测试");
            order.put("out_trade_no", dateTime);
            order.put("notify_url", Config.getWeixinMiniNotifyUrl().concat("/brand/payNotice"));
            JSONObject amount = new JSONObject();
            amount.put("total", (long)(0.01 * 100));
            amount.put("currency", "CNY");
            order.put("amount", amount);

            JSONObject payer = new JSONObject();
            payer.put("openid","ocJgy47Q1wBkgZEv7byIrgaQ9aSs");
            order.put("payer", payer);

            log.info(order.toJSONString());

            String privateKeyPath = wxPayConfig.getPrivateKeyPath();
            PrivateKey merchantPrivateKey = wxPayConfig.getPrivateKey(privateKeyPath);

            // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签，并进行证书自动更新

            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
            httpPost.addHeader("Accept", "application/json");
            httpPost.addHeader("Content-type","application/json; charset=utf-8");
            httpPost.setEntity(new StringEntity(order.toJSONString(), "UTF-8"));
            // 后面跟使用Apache HttpClient一样
            Verifier verifier = wxPayConfig.getVerifier();
            CloseableHttpClient wxPayClient = wxPayConfig.getWxPayClient(verifier);
            HttpResponse response = wxPayClient.execute(httpPost);
            String bodyAsString = EntityUtils.toString(response.getEntity());

            JSONObject bodyAsJSON = JSONObject.parseObject(bodyAsString);

            log.info(bodyAsJSON.toJSONString());
            if(bodyAsJSON.containsKey("code")) {
                return new ResultInfo(1, bodyAsJSON.getString("message"));
            }
            final String prepay_id = bodyAsJSON.getString("prepay_id");
            final String timeStamp = String.valueOf(System.currentTimeMillis());
//			long time = new Date().getTime();
            final String nonceStr = RandomStringGenerator.getRandomStringByLength(32);
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(Config.getWeixinMiniAppid() + "\n");
            stringBuffer.append(timeStamp + "\n");
            stringBuffer.append(nonceStr + "\n");
            stringBuffer.append("prepay_id="+prepay_id+"\n");
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(merchantPrivateKey);
            signature.update(stringBuffer.toString().getBytes("UTF-8"));
            byte[] signBytes = signature.sign();
            String paySign = Base64.encodeBytes(signBytes);

            JSONObject params = new JSONObject();
            params.put("appId", Config.getWeixinMiniAppid());
            params.put("timeStamp", timeStamp);
            params.put("nonceStr", nonceStr);
            params.put("package", "prepay_id="+prepay_id);
            params.put("signType", "RSA");
            params.put("paySign", paySign);


            return new ResultInfo<Object>(20000, params);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            log.info(e.toString());
            e.printStackTrace();
        }
        return null;

    }



    /**
     * 支付通知(api)
     */
    @RequestMapping(value="/payNotice")
    public void payNotice(
            HttpServletRequest request,
            HttpServletResponse response){
        try {
            String reqParams = StreamUtil.read(request.getInputStream());
            log.info("-------支付结果:"+reqParams);
            JSONObject json = JSONObject.parseObject(reqParams);

            String ciphertext = json.getJSONObject("resource").getString("ciphertext");
            final String associated_data = json.getJSONObject("resource").getString("associated_data");
            final String nonce = json.getJSONObject("resource").getString("nonce");
            AesUtil aesUtil = new AesUtil(Config.getWeixinMiniApiV3Key().getBytes());
            ciphertext = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);
            log.info("-------ciphertext:"+ciphertext);
            log.info(JSONObject.parseObject(ciphertext).getString("out_trade_no"));
            if(json.getString("event_type").equals("TRANSACTION.SUCCESS")){
                log.info("-------支付成功");
                shopOrderService.handleOrderNotify(ciphertext);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString());
        }
    }

    /**
     * 根据品牌名查询品牌
     * */
    @RequestMapping(value = "/getByName/{name}", method = RequestMethod.GET)
    public Result<List<ShopBrand>> getByName(@PathVariable String name) {
        List<ShopBrand> list = shopBrandService.getName(name);
        return new Result<>(list);
    }
}
